#include <kaleidoscope/frontend/semantic_analysis/resolver.hpp>
//=====================================================================
#include <atma/assert.hpp>
//=====================================================================
#include <kaleidoscope/common/symbol_ids.hpp>
#include <kaleidoscope/common/decorate.hpp>
#include <kaleidoscope/frontend/syntactical_analysis/marshall.hpp>
//=====================================================================
using namespace atma::sooty;
using namespace kal;
//=====================================================================

/*
size_t resolver::argument_type(atma::sooty::const_parseme_ptr_ref argument)
{
	if (argument->id == ids::int_literal)
		return ids::int_type;
	else
		return ids::identifier;
}

parseme_ptr resolver::find_closest_matching_function(const_parseme_ptr_ref function_call)
{
	// 0) save the state of our symbol tables
	symbol_table_state value_table_state = value_table().save_state();
	symbol_table_state type_table_state = type_table().save_state();
	
	parseme_ptr call_name = marshall::function_call::name(function_call);
	parseme_ptr call_PL = marshall::function_call::parameter_list(function_call);
	
	// get possible functions
	
	
	// we must go up through the scopes!
	//  - HEY: is there ever a case where we can be referencing a function defined in
	//    the SAME scope us code that could possibly call it? I can't think of a case.
	symbol_table::result_type::iterator candidate;
	symbol_table::result_type results;
	while ( value_table().leave_scope() && type_table().leave_scope() )
	{
		results = value_table().lookup(call_name->value.string);
		candidate = results.begin();
		for (; candidate != results.end(); ++candidate)
		{
			parseme_ptr_ref candidate_PL = marshall::function::parameter_list(*candidate);
			
			if (candidate_PL->children.size() != call_PL->children.size())
				continue;
			
			// argument-dependant lookup!
			bool match = true;
			parseme_container::iterator parameter = candidate_PL->children.begin();
			parseme_container::iterator argument = call_PL->children.begin();
			for ( ;; ++parameter, ++argument)
			{
				if (parameter == candidate_PL->children.end()) break;
				if (argument == call_PL->children.end()) break;
				
				parseme_ptr_ref cp_type = marshall::parameter::type(*parameter);
				// deduce our type from what it is
				size_t our_type = argument_type(*argument);
				
				//parseme_ptr_ref op_type = marshall::parameter::type(*op);
				
				if ( cp_type->id != our_type )
				{
					match = false;
					break;
				}
				else if ( cp_type->id == ids::identifier )
				{
					// user-defined types check here. hmm, scoping?
				}
			}
			
			if (match)
				break;
		}
	}
	
	// last) reinstate states
	value_table().load_from_state(value_table_state);
	type_table().load_from_state(type_table_state);
	
	return (candidate == results.end()) ? parseme::nullary : *candidate;
}


atma::sooty::parseme_ptr kal::resolver::find_value_in_scope(atma::sooty::const_parseme_ptr_ref scope)
{
	ATMA_ASSERT( scope->id == ids::function_body );
	
	// look through all this scope's children
	for (parseme_container::const_iterator i = scope->children.begin(); i != scope->children.end(); ++i)
	{
		const_parseme_ptr_ref node = *i;
		
		//if (node->id == ids::par
	}
}

kal::resolver::resolver( atma::sooty::symbol_table& value_table, atma::sooty::symbol_table& type_table ) : value_table_(&value_table), type_table_(&type_table)
{

}
*/